﻿using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using BCore.Identity.Users.Caching;
using Core.Caching;
using Core.Domain.Entities;
using Core.Domain.Enums;
using Core.Helpers;
using Core.Identity.Common.Interfaces.Common.Interfaces;
using Core.Models;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace Core.Identity.Users.Features.Commands.Create;

public class CreateUserCommand : ICacheInvalidatorRequest<Result<Guid>>
{
    /// <summary>
    /// 用户名
    /// </summary>
    [Required(ErrorMessage = "用户名必传")]
    public required string Username { get; set; }

    /// <summary>
    /// 密码
    /// </summary>
    [Required(ErrorMessage = "密码必传")]
    public required string Password { get; set; }

    /// <summary>
    /// 电子邮箱
    /// </summary>
    public string? Email { get; set; }
    /// <summary>
    /// 昵称
    /// </summary>
    public required string Nickname { get; set; }
    /// <summary>
    /// 手机号码
    /// </summary>
    public string? PhoneNumber { get; set; }
    /// <summary>
    /// 性别
    /// </summary>
    public GenderType Gender { get; set; }

    /// <summary>
    /// 组织机构
    /// </summary>
    public Guid? OrganizationId { get; set; }

    /// <summary>
    /// 设置描述
    /// </summary>
    public string? Description { get; set; }

    /// <summary>
    /// 设置启用/禁用
    /// </summary>
    public bool Enabled { get; set; }

    [JsonIgnore]
    public IEnumerable<string>? Tags => UsersCacheKey.Tags;
}

public class CreateUserCommandHandler(IIdentityDbContext dbContext) : IRequestHandler<CreateUserCommand, Result<Guid>>
{

    public async Task<Result<Guid>> Handle(CreateUserCommand request, CancellationToken cancellationToken)
    {
        var user = await dbContext.Users
            .FirstOrDefaultAsync(x => x.Username == request.Username, cancellationToken);
        ExceptionHelper.ThrowIfNotNull(user, "用户名已存在");

        if (!string.IsNullOrWhiteSpace(request.Email)) 
        {
            user = await dbContext.Users
                .FirstOrDefaultAsync(x => x.Email == request.Email, cancellationToken);
            ExceptionHelper.ThrowIfNotNull(user, "邮箱已被占用");
        }

        user = User.Create(request.Username, request.Password, request.Email);
        user.ChangeNickname(request.Nickname);
        user.SetPhoneNumber(request.PhoneNumber ?? "", false);
        user.SetGender(request.Gender);
        user.SetEnabled(request.Enabled);
        user.SetDescription(request.Description);

        await dbContext.Users.AddAsync(user);

        if (request.OrganizationId != null)
        {
            var organization = await dbContext.Organizations
            .FirstOrDefaultAsync(x => x.Id == request.OrganizationId, cancellationToken);
            ExceptionHelper.ThrowIfNull(organization, "组织不存在");

            var userOrganization = new UserOrganization(user, organization, OrganizationPosition.Member);

            await dbContext.UserOrganizations.AddAsync(userOrganization);
        }

        var result = await dbContext.SaveChangesAsync(cancellationToken) > 0;
        return await Result<Guid>.SucceedAsync(result, user.Id, ["创建失败"]);
    }
}
